package com.simple.shiro;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.simple.service.SysMenuService;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

/**
 * shiro配置
 */
@Configuration
public class ShiroConfig {
	
	@Autowired
	SysMenuService sysMenuService;
	
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //设置默认登录页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        //设置登录成功后的页面
        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unAuthorized");
        Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
        Map<String,Filter> customFilterMap=new LinkedHashMap<>();
        //自定义url拦截（初始环境可注掉）
        customFilterMap.put("requestURL", new CustomPathMatchingFilter());
        //拦截/user
        filterChainDefinitionMap.put("/user/logout.html","authc");
        filterChainDefinitionMap.put("/user/unAuthorized.html","anon");
        filterChainDefinitionMap.put("/user/index.html","authc");
        filterChainDefinitionMap.put("/user/sysUserLog.html","authc");
        filterChainDefinitionMap.put("/user/*","authc");
//        filterChainDefinitionMap.put("/user/*","requestURL");
        //filterChainDefinitionMap.put("/static/*","anon");
        shiroFilterFactoryBean.setFilters(customFilterMap);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //自定义session管理器
        securityManager.setSessionManager(sessionManager());
        //缓存
        //securityManager.setCacheManager(ehCacheManager());
        securityManager.setRealm(authRealm());
        return securityManager;
    }


    //自定义realm
    @Bean
    public AuthorizingRealm authRealm() {
        MyRealm realm=new MyRealm();
        realm.setCredentialsMatcher(HashedCredentialsMatcher());
        //授权缓存
        realm.setAuthenticationCachingEnabled(false);
        return realm;
    }

    //开启注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor sourceAdvisor=new AuthorizationAttributeSourceAdvisor();
        sourceAdvisor.setSecurityManager(securityManager());
        return sourceAdvisor;
    }

    @Bean
    public org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher() {
        org.apache.shiro.authc.credential.HashedCredentialsMatcher hash=new org.apache.shiro.authc.credential.HashedCredentialsMatcher();
        //加密方式 MD5
        hash.setHashAlgorithmName("MD5");
        //散列次数
        hash.setHashIterations(1024);
        return hash;
    }

    @Bean
    public ShiroSessionListener sessionListener() {
        ShiroSessionListener listener=new ShiroSessionListener();
        return listener;
    }
    
    //ShiroDialect  thymeleaf标签使用
    @Bean
    public ShiroDialect getShiroDialect() {
    	return new ShiroDialect();
    }
    
    @Bean
    public SessionManager sessionManager() {
        Collection<SessionListener> listeners = new ArrayList<SessionListener>();
        listeners.add(sessionListener());

        ShiroSessionManager sessionManager=new ShiroSessionManager();
        sessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
        sessionManager.setSessionListeners(listeners);
        //设置session过期时间 30分钟
        sessionManager.setGlobalSessionTimeout(1800000L);
        //设置sessionDAO
        sessionManager.setSessionDAO(getMemorySessionDAO());
        //设置cookie
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdCookie(sessionIdCookie());
        //缓存
        //sessionManager.setCacheManager(ehCacheManager());
        return sessionManager;
    }
    
    //配置sessionDAO
    @Bean(name="sessionDAO")
    public MemorySessionDAO getMemorySessionDAO() {
        MemorySessionDAO sessionDAO=new MemorySessionDAO();
        return sessionDAO;
    }
    //自定义cookie中的session名称
    @Bean
    public SimpleCookie sessionIdCookie() {
        SimpleCookie simpleCookie=new SimpleCookie();
        simpleCookie.setHttpOnly(true);//通过脚本无法获取到cookie信息
        simpleCookie.setName("shiroSession");
        return simpleCookie;
    }
}
